using System;
using System.Collections.Generic;
using System.Text;
using Decav.Gatsb.Data;
using Decav.Data;
using Decav.Gatsb.Application;
using System.Collections.ObjectModel;

namespace Decav.Gatsb
{
    /// <summary>
    /// Defines a post of an image or text that is made by a <see cref="User"/>, and usually linked to a
    /// particular <see cref="Location"/>.
    /// </summary>
    [Serializable]
    public class Post
    {
        private Post()
        {
            _id = Guid.NewGuid();
            _createDate = DateTime.UtcNow;
            _owner = GatsbApplication.Current.CurrentUser;
            _attachments = new PostAttachmentCollectionLazyLoadReference();
        }

        protected Post(DataRecordAdapter adapt)
        {
            if (adapt == null)
                throw new ArgumentNullException("adapt");

            _id = adapt.GetGuid("PostId");
            _createDate = adapt.GetDateTime("CreateDate");
            _subject = adapt.GetString("Subject");

            _location = new LocationLazyLoadReference(adapt.GetGuid("Location"));
            _body = adapt.GetString("Body");
            _owner = GatsbApplication.Current.GetUser(adapt.GetGuid("Owner"));
            _permissions = (PrivacyPermissionLevel)adapt.GetInt32("Permissions");
            _attachments = new PostAttachmentCollectionLazyLoadReference(_id);
        }
        
        private Guid _id;
        private DateTime _createDate;
        private string _subject;
        private string _body;
        private PrivacyPermissionLevel _permissions = PrivacyPermissionLevel.Public;
        private User _owner;
        private LocationLazyLoadReference _location;
        private PostAttachmentCollectionLazyLoadReference _attachments;

        /// <summary>
        /// Gets the unique identifier of the post.
        /// </summary>
        public Guid Id
        {
            get
            {
                return _id;
            }
        }

        /// <summary>
        /// Gets the date the post was created.
        /// </summary>
        public DateTime CreateDate
        {
            get
            {
                return _createDate;
            }
        }

        /// <summary>
        /// Gets or sets the title of the post, or null when not applicable.
        /// </summary>
        public string Subject
        {
            get
            {
                return _subject;
            }
            set
            {
                _subject = value;
            }
        }

        /// <summary>
        /// Gets the location that the post was made, or null when not assigned with a location.
        /// </summary>
        /// <remarks>
        /// This value is lazy loaded and may delay the method call due to a database
        /// request.
        /// </remarks>
        public Location Location
        {
            get
            {
                return _location.Value;
            }
        }

        /// <summary>
        /// Gets the unique identifier of the location that the <see cref="Post"/>
        /// was created in.
        /// </summary>
        public Guid LocationId
        {
            get
            {
                return _location.Id;
            }
        }

        /// <summary>
        /// Gets or sets the body text of the post.
        /// </summary>
        public string Body
        {
            get
            {
                return _body;
            }
            set
            {
                _body = value;
            }
        }

        /// <summary>
        /// Gets a collection of the items attached to the post.
        /// </summary>
        public Collection<PostAttachment> Attachments
        {
            get
            {
                return _attachments.Value;
            }
        }

        /// <summary>
        /// Gets the person who created the post.
        /// </summary>
        public User Owner
        {
            get
            {
                return _owner;
            }
        }

        /// <summary>
        /// Gets the permission levels of the post.
        /// </summary>
        public PrivacyPermissionLevel ViewPermissions
        {
            get
            {
                return _permissions;
            }
        }

        /// <summary>
        /// Creates a new <see cref="Post"/> by the <see cref="GatsbApplication.CurrentUser"/>.
        /// </summary>
        /// <returns>A new post by the current user.</returns>
        public static Post CreatePost(DateTime createDate, string body, Guid locationId)
        {
            Post p = new Post();
            p._createDate = createDate;
            p._body = body;
            p._location = new LocationLazyLoadReference(locationId);
            return p;
        }

        /// <summary>
        /// Creates a new <see cref="Post"/> by the <see cref="GatsbApplication.CurrentUser"/>.
        /// </summary>
        /// <returns>A new post by the current user.</returns>
        public static Post CreatePost(DateTime createDate, string body)
        {
            Post p = new Post();
            p._createDate = createDate;
            p._body = body;
            p._location = new LocationLazyLoadReference(Guid.Empty);
            return p;
        }
    }
}
